package com.jinzhu.common.exception;


import com.jinzhu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    /**
     * 处理参数校验失败异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.NOT_IMPLEMENTED)
    @ResponseBody
    public R bindException(MethodArgumentNotValidException e) {
        log.warn("参数校验失败：{}", e);
        BindingResult bindingResult = e.getBindingResult();
        List<FieldError> allErrors = bindingResult.getFieldErrors();
     return   R.error(HttpStatus.NOT_IMPLEMENTED.value(), "参数校验失败");
    }

    /**
     * 处理自定义的业务异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = MsException.class)
    @ResponseBody
    public R bizExceptionHandler(HttpServletRequest req, MsException e) {
        log.error("发生业务异常！原因是：{}", e.getErrorMsg());
        return R.error(e.getErrorCode(), e.getErrorMsg());
    }

    /**
     * 处理空指针的异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public R exceptionHandler(HttpServletRequest req, NullPointerException e) {
        log.error("发生空指针异常！原因是:", e);
        return R.error(CommonEnum.BODY_NOT_MATCH.getResultCode(), CommonEnum.BODY_NOT_MATCH.getResultMsg());
    }

    /**
     * 处理其他异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public R exceptionHandler(HttpServletRequest req, Exception e) {
        log.error("未知异常！原因是:", e);
        return R.error(CommonEnum.INTERNAL_SERVER_ERROR.getResultCode(), e.getMessage());
    }

    /**
     * 处理其他异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = AsyncRequestTimeoutException.class)
    @ResponseBody
    public String exceptionHandler(HttpServletRequest req, AsyncRequestTimeoutException e) {
        log.error("异步请求超时异常！原因是:", e);
        R error = R.error(CommonEnum.INTERNAL_SERVER_ERROR.getResultCode(), CommonEnum.INTERNAL_SERVER_ERROR.getResultMsg());
        return error.toString();
    }

    /**
     * 数据校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = DataValidateException.class)
    public Result dataValidateException(DataValidateException e) {
        log.error("数据校验异常", e.getDesc());
        return Result.error(e.getErrorCode(),e.getDesc());
    }

}
